#define _CRT_SECURE_NO_WARNINGS

#ifndef PCL_PROCESS_HPP
#define PCL_PROCESS_HPP

#include <cstdio>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

#include <opencv2/opencv.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/cloud_viewer.h> 
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_sphere.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/common/transforms.h>
#include <pcl/io/ply_io.h>


#define CLOUD_DENSITY_THRESHOULD 20 // 控制点云密度的阈值
#define BALLRADIUS 0.12 //排球半径（单位：m）
#define BALLRADIUS_MIN 0.1 //拟合后筛选的半径最小值
#define BALLRADIUS_MAX 0.15 //拟合后筛选的半径最大值
// #define CLOUD_SAVE //保存点云到文件夹
#define CLOUDPATH "./data/frame"
#define PCL_PAI 3.1415926f

using namespace std;
using namespace cv;
using namespace Eigen;

extern float OpsMsg_x,OpsMsg_y,OpsMsg_yaw;
extern float table_yaw;

typedef pcl::PointXYZ 			PointType;
typedef pcl::PointCloud<PointType> 	PointCloud;
typedef PointCloud::Ptr 		pPointCloud;

class PclProcess
{
public:
    PclProcess(const std::string &name);
    ~PclProcess();

    void Pcl_show_init();
    void Pcl_show(void);
    void Pcl_show(int& num);

    PointType get_ball_center(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_points, cv::Rect roiRect);
    PointType get_ball_center2(pPointCloud cloud_points, PointType reference_point);
    PointType get_ball_center_ransac(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_points, cv::Rect roiRect);
    pPointCloud cloud_clip_3d(pPointCloud cloud_points, PointType start_point, PointType end_point);
    void cloud_point_clear(void);
    void cloud_translation(pPointCloud cloud_points, float trans_x, float trans_y, float trans_z, 
                                                    float rotate_x, float rotate_y, float rotate_z);
    PointType cloud_translation(PointType cloud_point, float trans_x, float trans_y, float trans_z, 
                                                    float rotate_x, float rotate_y, float rotate_z);
    PointType Ball_Relative_To_World_Coordinate(float car_x, float car_y, float car_yaw, float table_yaw, PointType input_point);

    pPointCloud roi_cloud;  // YOLO框选区域的点云
    PointType center_point; // 计算出的球心坐标
    vector<string> cloud_allpath; //指定文件夹中所有文件的路径
    pcl::visualization::PCLVisualizer viewer;
    bool show_flag;

private:
    VectorXf FitterLeastSquareMethod(const pPointCloud pointCloud);
    void savePointCloud(pPointCloud cloud, string outpath);
    pPointCloud loadPointCloud(std::string path);
    vector<string> getpath(string dirpath);

    pPointCloud center_cloud;   // 经过处理后保留下来的较高质量的中心附近的点云
    pPointCloud cloud_sphere;   // 拟合后被认为是球面附近的点的点云
    struct timeval time_pcl;

};











#endif